package com.intelligent.ispc.web.controller;

import com.intelligent.ispc.common.dto.JsonPageResponseDto;
import com.intelligent.ispc.common.dto.JsonResponseDto;
import com.intelligent.ispc.common.utils.ApplicationException;
import com.intelligent.ispc.common.utils.ExceptionMessages;
import com.intelligent.ispc.core.service.EmailService;
import com.intelligent.ispc.foundation.mail.MailConfiguration;
import com.intelligent.ispc.foundation.mail.EmailStatus;
import com.intelligent.ispc.mail.MimeMailServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletRequest;
import java.util.List;

/**
 * Created by Peter on 15/11/23.
 */
@Controller
@RequestMapping(value = "/system")
public class SystemController {

    @Autowired
    private EmailService emailService;

    @Autowired
    private MimeMailServiceImpl mimeMailService;

    @RequestMapping(value = "email", method = RequestMethod.GET)
    public String email(Model model, ServletRequest request) {
        Subject subject = SecurityUtils.getSubject();
        if(!subject.isPermitted("system:email:view")) {
            return "error/noPermission";
        }
        return "system/emailList";
    }

    @ResponseBody
    @RequestMapping(value = "email/list")
    public JsonPageResponseDto listEmail(Model model){
        Subject subject = SecurityUtils.getSubject();
        if(!subject.isPermitted("system:email:view")) {
            return JsonPageResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }
        List<MailConfiguration> emailDtos = emailService.findAllEmails();
        model.addAttribute("emailDtos",emailDtos);
        JsonPageResponseDto json = JsonPageResponseDto.SUCCESS().setBody(emailDtos);
        json.setRecordsTotal(emailDtos.size());
        json.setRecordsFiltered(emailDtos.size());
        json.setDraw(0);
        return json;
    }

    @RequestMapping(value = "email/create", method = RequestMethod.GET)
    public String emailDetail(Model model, ServletRequest request) {
        Subject subject = SecurityUtils.getSubject();
        if(!subject.isPermitted("system:email:create")) {
            return "error/noPermission";
        }
        return "system/createEmail";
    }

    @ResponseBody
    @RequestMapping(value = "email/create", method = RequestMethod.POST)
    public JsonResponseDto create(MailConfiguration email, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if(!subject.isPermitted("system:email:create")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            if(email.getPort() == null) {
                if(email.getProtocol().equals("smtp")) {
                    email.setPort((short) 25);
                }
            }
            if(email.getTimeout() == null) {
                email.setTimeout(10000);
            }
            emailService.saveEmail(email);
        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
        return JsonResponseDto.SUCCESS();
    }

    @RequestMapping(value = "email/edit/{id}", method = RequestMethod.GET)
    public String editForm(@PathVariable("id") String id,Model model) {
        Subject subject = SecurityUtils.getSubject();
        if(!subject.isPermitted("system:email:edit")) {
            return "error/noPermission";
        }
        MailConfiguration emailDto = emailService.findByUuid(id);
        model.addAttribute("email",emailDto);
        return "system/editEmail";
    }

    @ResponseBody
    @RequestMapping(value = "email/update/{id}", method = RequestMethod.GET)
    public JsonResponseDto updateForm(@PathVariable("id") String id, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if(!subject.isPermitted("system:email:edit")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }
            MailConfiguration emailDto = emailService.findByUuid(id);
            model.addAttribute("email", emailDto);
            return JsonResponseDto.SUCCESS().setBody(emailDto);
        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
    }

    @ResponseBody
    @RequestMapping(value = "email/update", method = RequestMethod.POST)
    public JsonResponseDto update(@ModelAttribute("email") MailConfiguration emailDto, Model model) {
       try {
            Subject subject = SecurityUtils.getSubject();
            if(!subject.isPermitted("system:email:edit")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }
           if(emailDto.getPort() == null) {
               if(emailDto.getProtocol().equals("smtp")) {
                   emailDto.setPort((short) 25);
               }
           }
           if(emailDto.getTimeout() == null) {
               emailDto.setTimeout(10000);
           }
            emailService.updateEmail(emailDto);
            mimeMailService.invalidateAllEmailCache();
        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
        return JsonResponseDto.SUCCESS();
    }

    @ResponseBody
    @RequestMapping(value = "email/updateEmailStatus", method = RequestMethod.POST)
    public JsonResponseDto updateEmailStatus(@RequestParam("emailId") String emailId, @RequestParam("status") EmailStatus status, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if(!subject.isPermitted("system:email:edit")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }
            emailService.updateEmailStatus(emailId, status);
            mimeMailService.invalidateAllEmailCache();
        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }

        return JsonResponseDto.SUCCESS();
    }

    @ResponseBody
    @RequestMapping(value = "email/delete/{id}",method = RequestMethod.POST)
    public JsonResponseDto delete(@PathVariable("id") String id, Model models) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("system:email:delete")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }
            emailService.deleteEmail(id);
        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
        return JsonResponseDto.SUCCESS();
    }

    @ResponseBody
    @RequestMapping(value = "email/testEmail/{emailId}",method = RequestMethod.POST)
    public JsonResponseDto testEmail(@PathVariable("emailId") String id, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if(!subject.isPermitted("system:email:view")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }
            MailConfiguration emailDto = emailService.findByUuid(id);
            mimeMailService.testEmail(emailDto);
        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
        return JsonResponseDto.SUCCESS();
    }

    @ResponseBody
    @RequestMapping(value = "email/testEmail",method = RequestMethod.POST)
    public JsonResponseDto testEmail(@ModelAttribute("email") MailConfiguration emailDto, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if(!subject.isPermitted("system:email:view")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }
            mimeMailService.testEmail(emailDto);
        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
        return JsonResponseDto.SUCCESS();
    }
}
